// #define DEBUG

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdint.h>
#include <memory.h>

#include <stddef.h>
#include <getopt.h>
#include <ctype.h>

#ifndef VHDLSENDER_HEADER_H
#define VHDLSENDER_HEADER_H

//#define DEBUG_PRINT_ALL_BUFFER_CONTENT
#define OUTPUT_GENERATE_BLOCK_DATA

enum VC_TYPE {
    VC_4 = 4,
    VC_12 = 12
};

// vcTypeHeader_t定义
typedef struct {
    uint16_t logicalChannelID;
    uint16_t physicalChannelID;
    uint16_t SQ;
    uint16_t frameLength;
    uint16_t frameNum;

    enum VC_TYPE vcType; // 冗余

} __attribute__((packed)) vcTypeHeader_t;

// VC-4结构定义
// LOAD
typedef struct {
    uint8_t load[2340];
} __attribute__((packed)) vc4FrameLoad_t;

// BODY
typedef struct {
    uint16_t MFI;
    vc4FrameLoad_t LOAD;
} __attribute__((packed)) vc4FrameBody_t;

typedef struct {
    vcTypeHeader_t HEADER;
    vc4FrameBody_t BODY;
} __attribute__((packed)) vc4FrameFull_t;

// VC-12结构定义
typedef struct {
    uint8_t load[136];
} __attribute__((packed)) vc12FrameLoad_t;

typedef struct {
    uint16_t MFI;
    vc12FrameLoad_t LOAD;
} __attribute__((packed)) vc12FrameBody_t;

typedef struct {
    vcTypeHeader_t HEADER;
    vc12FrameBody_t BODY;
} __attribute__((packed)) vc12FrameFull_t;

enum GENERATE_DATA_TYPE {
    FIXED_60A1DA8E = 0,
    FIXED_LowerINC_HigherLOID = 1,
    FIXED_LogicINC = 2,
    FIXED_00TOFF = 3,
    INPUTFILE,

};

const size_t VC_FRAME_HEADER_LENGTH = sizeof(vcTypeHeader_t);

const size_t VC4_FRAME_FULL_LENGTH = sizeof(vc4FrameFull_t); // 单个VC-4帧结构,包含开销
const size_t VC4_FRAME_BODY_LENGTH = sizeof(vc4FrameBody_t);
const size_t VC4_FRAME_LOAD_LENGTH = sizeof(vc4FrameLoad_t);

const size_t VC12_FRAME_FULL_LENGTH = sizeof(vc12FrameFull_t); // 单个VC-12帧结构,包含开销
const size_t VC12_FRAME_BODY_LENGTH = sizeof(vc12FrameBody_t);
const size_t VC12_FRAME_LOAD_LENGTH = sizeof(vc12FrameLoad_t);

#endif

///////////////////////////////////////////////////////

void printVCTypeHeader(const vcTypeHeader_t *header) {
    printf("logicalChannelID: %hu\n", header->logicalChannelID);
    printf("physicalChannelID: %hu\n", header->physicalChannelID);
    printf("SQ: %u\n", header->SQ);
    printf("frameLength: %hu\n", header->frameLength);
    printf("frameNum: %hu\n", header->frameNum);

    // 冗余部分, release可以清除(大概)
    switch (header->vcType) {
        case VC_4:
            printf("vcType: VC_TYPE4\n");
            break;
        case VC_12:
            printf("vcType: VC_TYPE12\n");
            break;
        default:
            printf("vcType: Unknown\n");
            break;
    }
}

/**
 * @brief 通过要填充的数据长度(LOAD数) 得到填充完毕后一行的Frame数量.
 * @param bufferLength
 * @param vcType
 * @param splitedCols
 * @return
 */
size_t getFrameNumOneLineFromBufferLength(size_t bufferLength, enum VC_TYPE vcType, uint16_t splitedCols) {
    if (bufferLength == 0) {
        return 0;
    }

    // bufferLength 来的是需要承载的数据, 不包含开销, 所以这里是VCX_FRAME_LOAD_LENGTH
    size_t vcTypeLoadLength;
    size_t frameNum;

    switch (vcType) {
        case VC_4:
            vcTypeLoadLength = VC4_FRAME_LOAD_LENGTH;
            break;
        case VC_12:
            vcTypeLoadLength = VC12_FRAME_LOAD_LENGTH;
            break;
        default:
            vcTypeLoadLength = VC4_FRAME_LOAD_LENGTH;
            break;
    }

    frameNum = bufferLength / (splitedCols * vcTypeLoadLength);
    if (bufferLength % (splitedCols * vcTypeLoadLength) != 0) {
        frameNum++;
    }

    return frameNum;
}

size_t getFrameNumOneLineFromOneLineLength(enum VC_TYPE vcType, size_t oneLineLength) {
    if (oneLineLength == 0) {
        return 0;
    }

    // 一行减去头, 剩下的空间是多个BODY
    size_t body_s = oneLineLength - VC_FRAME_HEADER_LENGTH;

    size_t vcTypeBodyLength;
    switch (vcType) {
        case VC_4:
            vcTypeBodyLength = VC4_FRAME_BODY_LENGTH;
            break;
        case VC_12:
            vcTypeBodyLength = VC12_FRAME_BODY_LENGTH;
            break;
        default:
            vcTypeBodyLength = VC4_FRAME_BODY_LENGTH;
            break;
    }

    return body_s % vcTypeBodyLength == 0 ? body_s / vcTypeBodyLength
                                          : (body_s / vcTypeBodyLength) + 1;
}

/**
 * @brief 通过要填充的数据长度(LOAD数) 得到填充完毕后的总的Frame数量, (一行的数量 * splitedCols)
 * @param bufferLength
 * @param vcType
 * @param splitedCols
 * @return
 */
size_t getFrameNumFromBufferLength(size_t bufferLength, enum VC_TYPE vcType, uint16_t splitedCols) {
    return getFrameNumOneLineFromBufferLength(bufferLength, vcType, splitedCols) * splitedCols;
}

size_t getTotalFullLengthOneLineFromBufferLength(size_t bufferLength, enum VC_TYPE vcType, uint16_t splitedCols) {
    if (bufferLength == 0 || splitedCols == 0) {
        return 0;
    }

    size_t vcTypeBodyLength;

    switch (vcType) {
        case VC_4:
            vcTypeBodyLength = VC4_FRAME_BODY_LENGTH;
            break;
        case VC_12:
            vcTypeBodyLength = VC12_FRAME_BODY_LENGTH;
            break;
        default:
            vcTypeBodyLength = VC4_FRAME_BODY_LENGTH;
            break;
    }
    return (getFrameNumOneLineFromBufferLength(bufferLength, vcType, splitedCols) * vcTypeBodyLength) +
           VC_FRAME_HEADER_LENGTH;
}

/**
 * @brief 通过要填充的数据长度(LOAD数) 得到填充完毕后的总的数据长度数 (FULL LENGTH)
 * @param bufferLength 要填充的数据长度
 * @param vcType VC数据类型
 * @param splitedCols SQ值
 * @return 填充完毕后的总的数据长度数
 */
size_t getTotalFullLengthFormBufferLength(size_t bufferLength, enum VC_TYPE vcType, uint16_t splitedCols) {
    return getTotalFullLengthOneLineFromBufferLength(bufferLength, vcType, splitedCols) * splitedCols;
}

size_t getBufferLengthFromGenFrameNum(size_t genTotalFrameNum, enum VC_TYPE vcType) {
    // genFrameNum should be TIMES of split_channel number

    size_t loadLength;

    switch (vcType) {
        case VC_4:
            loadLength = VC4_FRAME_LOAD_LENGTH;
            break;

        case VC_12:
            loadLength = VC12_FRAME_LOAD_LENGTH;
            break;
    }

    return genTotalFrameNum * loadLength;
}

/**
 * @brief 通过memset全零填充
 *
 * @param buffer 已经分配的空间指针
 * @param filledLength 已经分配的空间大小
 * @return 填充的字节数
 */
size_t fillBlockWithZero(uint8_t *buffer, size_t filledLength) {
    // 开始全零填充
#ifdef DEBUG
    printf("全零填充前:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");
#endif // DEBUG

    memset(buffer, 0x00, filledLength);

#ifdef DEBUG
    printf("全零填充后:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");
#endif // DEBUG

    // 返回填充后的长度
    return filledLength;
}

/**
 * @brief 通过memset填充指定的单字节数据
 * @param buffer 已经分配的空间指针
 * @param filledLength 已经分配的空间大小
 * @param value 将填充的单字节指
 * @return 填充的字节数
 */
size_t fillBlockWithSpecificValue(uint8_t *buffer, size_t filledLength, uint8_t value) {
    // 开始全零填充
#ifdef DEBUG
    printf("全零填充前:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");
#endif // DEBUG

    memset(buffer, value, filledLength);

#ifdef DEBUG
    printf("全零填充后:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");
#endif // DEBUG

    // 返回填充后的长度
    return filledLength;
}

size_t generatePersistData_00toFF(uint8_t *buffer, size_t bufferLength, size_t filledLength) {
    if (buffer == NULL || filledLength == 0) {
        return 0; // 无效的输入参数，不进行填充
    }
    // 全零填充
    fillBlockWithZero(buffer, bufferLength);

    size_t filledBytes = 0;
    for (size_t i = 0; i < filledLength; i++) {
        buffer[i] = i;
        filledBytes++;

        if (filledBytes >= filledLength) {
            break; // 已经填充满 buffer
        }
    }

    // 继续填充为零
    for (size_t i = filledBytes; i < filledLength; i++) {
        buffer[i] = 0x00;
    }
#ifdef DEBUG
    printf("填充后:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");

#endif // DEBUG
    // 填充数据结束

    return filledBytes;
}

/**
 * @brief 产生固定数据, 数据写死为0x60A1DA8E, 函数首先会将这个数据块全零填充, 后续将按照 0-filledLength 的范围填充数据, 剩余的空间填充0
 *
 * @param buffer 已经分配的空间指针
 * @param bufferLength 已经分配的空间长度
 * @param filledLength 将要填充的数据字节数
 * @return 填充的字节数
 */
size_t generatePersistData_60A1DA8E(uint8_t *buffer, size_t bufferLength, size_t filledLength) {
    if (buffer == NULL || filledLength == 0) {
        return 0; // 无效的输入参数，不进行填充
    }
    // 全零填充
    fillBlockWithZero(buffer, bufferLength);

    // 开始填充数据
    // 使用PDF中说要填充的固定数据为: 0x60A1DA8E, 这很明显是一个4Bytes的数据, 有可能需要检验buffer的大小是不是4Bytes的整数倍.
    const size_t patternLength = 4; // 0x60A1DA8E 是4个字节
    const uint8_t pattern[] = {0x60, 0xA1, 0xDA, 0x8E};
    size_t filledBytes = 0;

    for (size_t i = 0; i < filledLength; i++) {
        buffer[i] = pattern[i % patternLength];
        filledBytes++;

        if (filledBytes >= filledLength) {
            break; // 已经填充满 buffer
        }
    }

    // 继续填充为零
    for (size_t i = filledBytes; i < filledLength; i++) {
        buffer[i] = 0x00;
    }
#ifdef DEBUG
    printf("填充后:\n");
    for (size_t i = 0; i < filledLength; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");

#endif // DEBUG
    // 填充数据结束

    return filledBytes;
}

// generate target 1:
size_t generatePersistData_LowerIncrementHigherLogicalID(uint8_t *buffer, size_t bufferLength, size_t filledLength,
                                                         uint16_t logicChannelID) {
    if (buffer == NULL || filledLength > bufferLength) {
        return 0; // 输入参数不合法
    }

    uint16_t lowerValue = 0; // 初始低 2 字节值为 0
    size_t bytesFilled = 0;

    for (size_t i = 0; i < filledLength; i += 4) {
        if (bytesFilled + 4 <= bufferLength) {
            // 将低 2 字节值复制到 buffer 中
            buffer[bytesFilled] = lowerValue & 0xFF;
            buffer[bytesFilled + 1] = (lowerValue >> 8) & 0xFF;

            // 将高 2 字节值（逻辑通道号）复制到 buffer 中
            buffer[bytesFilled + 2] = logicChannelID & 0xFF;
            buffer[bytesFilled + 3] = (logicChannelID >> 8) & 0xFF;

            // 循环递增低 2 字节值
            lowerValue = (lowerValue + 1) & 0xFFFF;

            bytesFilled += 4;
        } else {
            break; // 数据块已填充完毕
        }
    }

    return bytesFilled;
}

size_t generatePersistData_ChannelIncrement(uint8_t *buffer, size_t bufferLength, size_t filledLength,
                                            uint16_t logicChannelID) {
    if (buffer == NULL || filledLength == 0) {
        return 0; // 输入参数不合法
    }

    size_t bytesFilled = 0;
    uint16_t tempLogicChannelID = logicChannelID;

    for (size_t i = 0; i < filledLength; i += 4) {
        if (bytesFilled + 4 <= bufferLength) {
            // 将初始值（4个字节的0）复制到 buffer 中
            buffer[bytesFilled] = 0;
            buffer[bytesFilled + 1] = 0;
            buffer[bytesFilled + 2] = 0;
            buffer[bytesFilled + 3] = 0;

            // 递增值（逻辑通道号）复制到 buffer 中
            buffer[bytesFilled] = tempLogicChannelID & 0xFF;
            buffer[bytesFilled + 1] = (tempLogicChannelID >> 8) & 0xFF;

            // 循环递增逻辑通道号
            tempLogicChannelID = (tempLogicChannelID + logicChannelID) & 0xFFFF;

            bytesFilled += 4;
        } else {
            break; // 数据块已填充完毕
        }
    }

    return bytesFilled;
}


bool reverseBufferInPlace(uint8_t *buffer, size_t length) {
    if (buffer == NULL || length <= 1) {
        return false; // 无效的输入参数或数据长度太短，不进行翻转
    }

    // 使用两个指针，从头和尾同时向中间遍历，交换数据
    uint8_t temp;
    for (size_t i = 0, j = length - 1; i < j; i++, j--) {
        temp = buffer[i];
        buffer[i] = buffer[j];
        buffer[j] = temp;
    }
#ifdef DEBUG
    printf("翻转后:\n");
    for (size_t i = 0; i < length; i++)
    {
        printf("%02X ", (unsigned char)buffer[i]);
    }
    printf("\n");

#endif // DEBUG
    return true;
}

void reverseBufferWithExtraBuffer(const uint8_t *originBuffer, size_t length, uint8_t *outBuffer) {
    if (originBuffer == NULL || outBuffer == NULL || length == 0) {
        return; // 无效的输入参数，不进行翻转
    }

    // 使用两个指针，从头和尾同时向中间遍历，翻转数据并保存到 outBuffer
    for (size_t i = 0; i < length; i++) {
        outBuffer[i] = originBuffer[length - 1 - i];
    }
#ifdef DEBUG
    printf("翻转后:\n");
    for (size_t i = 0; i < length; i++)
    {
        printf("%02X ", (unsigned char)outBuffer[i]);
    }
    printf("\n");

#endif // DEBUG
}

size_t splitIntoMutipleBuffer(const uint8_t *buffer, size_t bufferLength, enum VC_TYPE vcType, uint16_t splitedCols,
                              size_t outBufferOneLineLength, uint8_t outBuffer[splitedCols][outBufferOneLineLength]) {
    if (buffer == NULL || bufferLength == 0 || splitedCols <= 0 || outBuffer == NULL) {
        return 0; // 输入参数不合法
    }

    size_t headerSize = VC_FRAME_HEADER_LENGTH;

    size_t fullSize;
    size_t bodySize;
    size_t loadSize;
    switch (vcType) {
        case VC_4:
            fullSize = VC4_FRAME_FULL_LENGTH;
            bodySize = VC4_FRAME_BODY_LENGTH;
            loadSize = VC4_FRAME_LOAD_LENGTH;
            break;
        case VC_12:
            fullSize = VC12_FRAME_FULL_LENGTH;
            bodySize = VC12_FRAME_BODY_LENGTH;
            loadSize = VC12_FRAME_LOAD_LENGTH;
            break;
        default:
            fullSize = VC4_FRAME_FULL_LENGTH;
            bodySize = VC4_FRAME_BODY_LENGTH;
            loadSize = VC4_FRAME_LOAD_LENGTH;
            break;
    }

    size_t oneLineFrameNum = getFrameNumOneLineFromBufferLength(bufferLength, vcType, splitedCols);

    //    // 这个部分填充是header部分
    //
    //    for (size_t lineFrameNum = 0; lineFrameNum < oneLineFrameNum; lineFrameNum++) {
    //        for (size_t sq = 0; sq < splitedCols; sq++) {
    //            for (size_t bytes = 0; bytes < VC_FRAME_HEADER_LENGTH; bytes++) {
    //                outBuffer[sq][bytes + lineFrameNum * fullSize] = 0x00;
    //            }
    //        }
    //    }
    //    // 因为后续有专门的函数处理头的部分, 本来想在一个函数中处理完成的, 后来觉的这个不应该, 也不方便debug.

    // 这个部分填充的是LOAD.
    size_t originBufferSeek = 0;
    for (size_t currLineFrameNum = 0;
         currLineFrameNum < oneLineFrameNum; currLineFrameNum++) { // lineFrameNum作为定位计数使用.
        for (size_t bytes = headerSize + sizeof(uint16_t);
             bytes < headerSize + bodySize; bytes++) { // 针对每个字节, HEADER + MFI作为写入开始,
            for (size_t sq = 0; sq < splitedCols; sq++) { // 遍历SQ放入.
                if (originBufferSeek < bufferLength) {
                    outBuffer[sq][bytes + bodySize * currLineFrameNum] = buffer[originBufferSeek];
                    //                    printf("sq: %zu, bytes + fullSize * currLineFrameNum = %zu\n", sq, bytes + fullSize * currLineFrameNum);
                    //                    *(outBuffer[sq] + bytes + fullSize * currLineFrameNum) = *(buffer + originBufferSeek);
                    //                    *(outBuffer + (sq * outBufferOneLineLength) + (bytes + fullSize * currLineFrameNum)) = *(buffer + originBufferSeek);
                    //                     最终证明: 上面的三种写法都可以, 因为编译器内存对齐的原因, for中的条件 bytes < fullSize 改为 bytes < headerSize + loadSize即可.
                    //                      在编译器中开启 __attribute__((packed)) 可以通知编译器不做字节为对齐.
                    originBufferSeek++;
                } else {
                    break; // 如果填充完毕, 后面的原始数据不动
                }
            }
        }
    }

    return originBufferSeek;
}

vcTypeHeader_t
generateHeaderWithSpecificValue(enum VC_TYPE vcType, uint16_t logicalChannelID, uint16_t physicalChannelID, uint16_t SQ,
                                size_t frameLength, uint16_t frameNum) {
    vcTypeHeader_t pattern;

    pattern.logicalChannelID = logicalChannelID;
    pattern.physicalChannelID = physicalChannelID;
    pattern.SQ = SQ;
    pattern.vcType = vcType;
    pattern.frameLength = frameLength;
    pattern.frameNum = frameNum;

    return pattern;
}

void fillHeaderWithSpecificValue(vcTypeHeader_t *target, enum VC_TYPE vcType, uint16_t logicalChannelID,
                                 uint16_t physicalChannelID, uint16_t SQ,
                                 size_t frameLength, uint16_t frameNum) {
    target->logicalChannelID = logicalChannelID;
    target->physicalChannelID = physicalChannelID;
    target->SQ = SQ;
    target->vcType = vcType;
    target->frameLength = frameLength;
    target->frameNum = frameNum;
}

bool fillHeaderToSplitFrameBuffersWithColIndex(vcTypeHeader_t headerData, uint16_t splitedCols,
                                               size_t inputBufferOneLineLength,
                                               uint8_t inputBuffer[splitedCols][inputBufferOneLineLength],
                                               size_t targetColFirstFrameIndex) {
    // 这个函数不应该在其中加入处理任何HEADER的函数, 非常单纯给一个HEADER和一个位置信息往里面写就完了.
    if (inputBuffer == NULL || inputBufferOneLineLength <= 0 || splitedCols <= 0) {
        return false;
    }

    if (targetColFirstFrameIndex > splitedCols - 1) {
        // 超过要填充的范围.
        return false;
    }

    // 仅填充一个header部分
    // Col是列
    uint8_t headerDataArr[sizeof(vcTypeHeader_t)];
    // HEADER的数据变成字节数组的形式
    memcpy_s(headerDataArr, sizeof(vcTypeHeader_t), &headerData, sizeof(vcTypeHeader_t));

    for (size_t currByte = 0; currByte < VC_FRAME_HEADER_LENGTH; ++currByte) {
        inputBuffer[targetColFirstFrameIndex][currByte] = (uint8_t) headerDataArr[currByte];
    }
    return true;
}

void fillHeadersToSplitBuffer(vcTypeHeader_t startHeader, enum VC_TYPE vcType, uint16_t splitedCols,
                              size_t inputBufferOneLineLength,
                              uint8_t inputBuffer[splitedCols][inputBufferOneLineLength]) {
    vcTypeHeader_t patternHeader = startHeader;

    size_t frameLen;
    switch (vcType) {
        case VC_4:
            frameLen = VC4_FRAME_FULL_LENGTH;
            break;
        case VC_12:
            frameLen = VC12_FRAME_FULL_LENGTH;
            break;
        default:
            frameLen = VC4_FRAME_FULL_LENGTH;
            break;
    }

    // 填充部分
    size_t totalColNum = splitedCols;

    for (size_t currCol = 0; currCol < totalColNum; ++currCol) {
        // 如果传入一个HEADER, 保持physID和logicID不变就可以了.
        // 处理header部分.
        // TODO: 这里的physicalID应该随着输出的HEADER的变化而变化.
        //        patternHeader.physicalChannelID = inputPhysicalID + currCol;
        //        有关与校验的部分应该放在外面的传入startHeader函数中.
        patternHeader.physicalChannelID = startHeader.physicalChannelID + currCol;

        patternHeader.SQ = currCol % totalColNum; // 有几行就是 0到几

        // TODO: 这里可能出现frameNum不能容纳一行的Length的情况.  暂时 % 4096 不让他溢出好了
        patternHeader.frameNum =
                getFrameNumOneLineFromOneLineLength(vcType, inputBufferOneLineLength);

        patternHeader.frameLength = frameLen;

        // TODO: vcType. 冗余单位.
        patternHeader.vcType = vcType;

        fillHeaderToSplitFrameBuffersWithColIndex(patternHeader, splitedCols, inputBufferOneLineLength, inputBuffer,
                                                  currCol);
    }
}

void headerReaderFromSplitBuffer(uint16_t splitedCols,
                                 size_t inputBufferOneLineLength,
                                 uint8_t inputBuffer[splitedCols][inputBufferOneLineLength]) {
    vcTypeHeader_t pattern;

    for (size_t i = 0; i < splitedCols; i++) {
        printf("outerBuffer[%zu]:\n", i);

        // 打印HEADER部分
        printf("HEADER:\n");
        for (size_t j = 0; j < VC_FRAME_HEADER_LENGTH; ++j) {
            printf("%02X ", (uint8_t) inputBuffer[i][j]);
        }
        printf("\n");
        memcpy_s(&pattern, sizeof(vcTypeHeader_t), inputBuffer[i], sizeof(vcTypeHeader_t));
        // todo: 验证

        printVCTypeHeader(&pattern);
        printf("\n");
    }
}


bool fillMFIToSplitBuffer(enum VC_TYPE vcType, uint16_t splitedCols,
                          size_t inputBufferOneLineLength,
                          uint8_t inputBuffer[splitedCols][inputBufferOneLineLength], uint16_t startMFI) {

    if (inputBuffer == NULL || inputBufferOneLineLength <= 0 || splitedCols <= 0) {
        return false;
    }

    size_t bodySize;
    switch (vcType) {
        case VC_4:
            bodySize = VC4_FRAME_BODY_LENGTH;
            break;
        case VC_12:
            bodySize = VC12_FRAME_BODY_LENGTH;
            break;
        default:
            // 碰到了不认识的type;
            return false;

            bodySize = VC4_FRAME_BODY_LENGTH;
            break;
    }

    uint16_t currMFI = startMFI;
    uint8_t tempMFI[sizeof(startMFI)];

    size_t oneLineFrameNum = getFrameNumOneLineFromOneLineLength(vcType, inputBufferOneLineLength);
    for (size_t currLineFrameNum = 0; currLineFrameNum < oneLineFrameNum; ++currLineFrameNum) {
        for (uint16_t currCol = 0; currCol < splitedCols; ++currCol) {
            for (size_t bytes = 0; bytes < sizeof(startMFI); ++bytes) {
                memcpy_s(&tempMFI, sizeof(tempMFI), &currMFI, sizeof(startMFI));
                inputBuffer[currCol][bytes + (bodySize * currLineFrameNum) + VC_FRAME_HEADER_LENGTH] = tempMFI[bytes];
            }
        }
        currMFI++, currMFI %= 4096;
    }
    return true;
}

unsigned char *loadFileToMemory(const char *filename, size_t *file_size) {
    FILE *file = fopen(filename, "rb"); // 以二进制只读方式打开文件
    if (!file) {
        perror("Error opening file");
        return NULL;
    }

    fseek(file, 0, SEEK_END);  // 将文件指针移到文件末尾
    size_t size = ftell(file); // 获取文件大小
    fseek(file, 0, SEEK_SET);  // 将文件指针移到文件开头

    if (size <= 0) {
        fclose(file);
        return NULL;
    }

    // 分配内存来存储文件内容
    unsigned char *buffer = (unsigned char *) malloc(size);
    if (!buffer) {
        fclose(file);
        return NULL;
    }

    // 将文件内容读取到内存中
    size_t bytes_read = fread(buffer, 1, size, file);
    if (bytes_read != (size_t) size) {
        fclose(file);
        free(buffer);
        return NULL;
    }

    // 关闭文件并返回文件内容和文件大小
    fclose(file);
    if (file_size) {
        *file_size = (size_t) size;
    }
    return buffer;
}

size_t generateGeneralData(enum GENERATE_DATA_TYPE type, uint8_t *buffer, size_t bufferLength, size_t filledLength) {
    switch (type) {
        case FIXED_60A1DA8E:
            generatePersistData_60A1DA8E(buffer, bufferLength, filledLength);
            break;
        case FIXED_00TOFF:
            generatePersistData_00toFF(buffer, bufferLength, filledLength);
            break;

        case INPUTFILE:
            exit(EXIT_FAILURE);
            break;
    }

    return 0;
}

void outputOriginBufferToFile(const char *filename, const uint8_t *buffer, size_t bufferLength) {
    // 打开文件
    FILE *file = fopen(filename, "w+b"); // 以二进制写入模式打开文件

    if (file != NULL) {
        // 将数据写入文件
        size_t bytesWritten = fwrite(buffer, sizeof(char), bufferLength, file);

        if (bytesWritten != bufferLength) {
            // 写入失败
            printf("\033[31mERROR: \033[0m writing data to file FAIL.\n");
        } else {
            // 写入成功
            printf("GenerateData '%s' successfully written to file.\n", filename);
        }

        // 关闭文件
        fclose(file);
    } else {
        // 文件打开失败
        printf("\033[31mERROR: \033[0m opening file: %s FAIL.\n\n", filename);
    }
}

bool outputToFiles(uint16_t splitedCols, size_t inputBufferOneLineLength,
                   uint8_t inputBuffer[splitedCols][inputBufferOneLineLength], uint16_t startPhysicalID) {

    // 假设有5个文件分别为 file1.txt, file2.txt, file3.txt, file4.txt, file5.txt
    // 将这5个文件依次打开，并将每个文件的内容分别存入 inputBuffer 中对应行的所有字节
    for (size_t currCol = 0; currCol < splitedCols; currCol++) {
        char filename[20];
        sprintf(filename, "Data_PhysicalChannel_%u.dat", startPhysicalID); // 生成文件名，例如：file1.txt, file2.txt, ...

        FILE *file = fopen(filename, "w+b");
        if (file == NULL) {
            printf("\033[31mERROR: \033[0m opening file: %s ERROR.\n", filename);
            return false;
        }

        // 将 inputBuffer 的第 currCol 行读取到文件内容中
        size_t bytesFilled = fwrite(inputBuffer[currCol], sizeof(char), inputBufferOneLineLength, file);
        printf("File: %s, filled Bytes %zu.\n\n", filename, bytesFilled);
        startPhysicalID++;

        fclose(file);
    }
    printf("\n");

    return true;
}

void printHeapBufferMemory(const void *mallocPtr, size_t bufferSize) {
    const uint8_t *byte_ptr = (const uint8_t *) mallocPtr;

    for (size_t i = 0; i < bufferSize; ++i) {
        printf("%02X ", byte_ptr[i]); // 以十六进制格式打印每个字节
    }
    printf("\n");
}

void printHeapBufferMemoryLast20Bytes(const void *mallocPtr, size_t bufferSize) {
    const uint8_t *byte_ptr = (const uint8_t *) mallocPtr;
    for (size_t i = bufferSize - 20; i < bufferSize; ++i) {
        printf("%02X ", byte_ptr[i]); // 以十六进制格式打印每个字节
    }
    printf("\n");
}

void printHeapOutterBufferContent(enum VC_TYPE vcType, uint16_t splitedCols,
                                  size_t bufferOneLineLength,
                                  uint8_t outBuffer[splitedCols][bufferOneLineLength]) {
    size_t vcBodyLength;
    switch (vcType) {
        case VC_4:
            vcBodyLength = VC4_FRAME_BODY_LENGTH;
            break;
        case VC_12:
            vcBodyLength = VC12_FRAME_BODY_LENGTH;
            break;
    }

    for (size_t i = 0; i < splitedCols; i++) {
        printf("outerBuffer[%zu]:\n", i);

        // 打印HEADER部分
        printf("HEADER:\n");
        for (size_t j = 0; j < VC_FRAME_HEADER_LENGTH; ++j) {
            printf("%02X ", (uint8_t) outBuffer[i][j]);
        }
        printf("\n");

        // 打印BODY部分
        printf("BODY:\n");
        for (size_t j = VC_FRAME_HEADER_LENGTH; j < bufferOneLineLength; j++) {
            //            if ((j - VC_FRAME_HEADER_LENGTH) % vcBodyLength == 0){
            if ((j - VC_FRAME_HEADER_LENGTH) % vcBodyLength == 0 && j != VC_FRAME_HEADER_LENGTH) {
                printf("\n");
            }
            printf("%02X ", (uint8_t) outBuffer[i][j]);
        }
        printf("\n\n");
    }
    printf("\n");
}

void testAllFunctionsWithMalloc() {
    ///////////////////////////////////////////////////////////////  variable declare unit test
    uint16_t defaultSplitedCols = 6;
    enum VC_TYPE defaultVCType = VC_12;

    uint16_t defaultStartMFI = 4000;
    uint16_t defaultLogicalID = 10;
    uint16_t defaultPhysicalID = 0;
    uint16_t defaultSQ = 0;

    const size_t filledBufferLength = 99999999; // 要填充的 buffer 的长度
    const size_t bufferLength = 99999999;       // 总 buffer 长度

    printf("defaultSplitedCols: %d\n", defaultSplitedCols);
    printf("defaultStartMFI: %d\n", defaultStartMFI);
    printf("defaultLogicalID: %d\n", defaultLogicalID);
    printf("defaultPhysicalID: %d\n", defaultPhysicalID);
    printf("defaultSQ: %d\n", defaultSQ);
    printf("defaultVCType: %s\n", defaultVCType == VC_4 ? "VC_4" : defaultVCType == VC_12 ? "VC_12"
                                                                                          : "Unknown vcType");

    printf("\n");
    ///////////////////////////////////////////////////////////////  malloc heap memory unit test
    void *mallocBuffer = malloc(bufferLength); // 分配空间
    printf("mallocBuffer origin data: %zu \n", bufferLength);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    ///////////////////////////////////////////////////////////////  fillBlockWithSpecificValue unit test
    fillBlockWithZero(mallocBuffer, filledBufferLength);
    printf("fillBuffer with 0: \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif
    fillBlockWithSpecificValue(mallocBuffer, bufferLength, 0xBB);
    printf("fillBuffer with BB: \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif
    printf("\n");

    ///////////////////////////////////////////////////////////////  generatePersistData unit test
    generatePersistData_00toFF(mallocBuffer, bufferLength, filledBufferLength);
    //    generatePersistData_60A1DA8E(mallocBuffer, bufferLength, filledBufferLength);

    printf("generatePersistData: \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    printf("Only print LAST 20 Bytes:\n");
    printHeapBufferMemoryLast20Bytes(mallocBuffer, bufferLength);

    printf("\n");
    ///////////////////////////////////////////////////////////////  reversePersistData unit test
    printf("reverseBufferInPlace: \n");
    printf("reversed      test: \n");
    reverseBufferInPlace(mallocBuffer, bufferLength);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    printf("reversed to origin: \n");
    reverseBufferInPlace(mallocBuffer, bufferLength);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    void *mallocBuffer2 = malloc(bufferLength);
    reverseBufferWithExtraBuffer(mallocBuffer, bufferLength, mallocBuffer2);
    printf("reversed to extra : \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer2, bufferLength);
#endif
    free(mallocBuffer2);
    printf("ExtraBuffer data freed! \n");

    printf("\n");
    ///////////////////////////////////////////////////////////////  getters unit test

    size_t testGettersNum1 = getFrameNumOneLineFromBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    printf("getFrameNumOneLineFromBufferLength() returns: %zu\n", testGettersNum1);
    size_t testGettersNum2 = getFrameNumFromBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    printf("getFrameNumFromBufferLength() returns: %zu\n", testGettersNum2);
    size_t testGettersNum3 = getTotalFullLengthOneLineFromBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    printf("getTotalFullLengthOneLineFromBufferLength: %zu\n", testGettersNum3);
    size_t testGettersNum4 = getTotalFullLengthFormBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    printf("getTotalFullLengthFormBufferLength: %zu\n", testGettersNum4);
    size_t testGettersNum5 = getFrameNumOneLineFromOneLineLength(defaultVCType, testGettersNum3);
    printf("getFrameNumOneLineFromOneLineLength: %zu\n", testGettersNum5);

    printf("\n");
    ///////////////////////////////////////////////////////////////  fillDataToSplitBuffer unit test

    printf("/////////////////////////////////////////////////////////////////////////////////////////////////////////////\n");
    printf("fillDataToSplitBuffer test start!\n\n");

    size_t oneLineLength = getTotalFullLengthOneLineFromBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    void *outMallocBuffer = malloc(getTotalFullLengthFormBufferLength(bufferLength, defaultVCType, defaultSplitedCols));
    if (outMallocBuffer) {
        printf("outBufferMalloced!\n");
    } else {
        printf("outBufferMalloc ERROR!\n");
        return;
    }

    printf("fillBlockWithSpecificValue: 0xBB\n");
    fillBlockWithSpecificValue(outMallocBuffer,
                               getTotalFullLengthFormBufferLength(bufferLength, defaultVCType, defaultSplitedCols),
                               0xBB);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapOutterBufferContent(defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("\n");
    ///////////////////////////////////////////////////////////////  fillSplitDataToSplitBuffer unit test

    printf("splitIntoMutipleBuffer: \n");
    splitIntoMutipleBuffer(mallocBuffer, bufferLength, defaultVCType, defaultSplitedCols, oneLineLength,
                           outMallocBuffer);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    printHeapOutterBufferContent(defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("\n");
    //////////////////////////////////////////////////////////////  fillHeaders unit test

    size_t totalFrameSize = getTotalFullLengthFormBufferLength(bufferLength, defaultVCType, defaultSplitedCols);
    size_t totalFrameNum = getFrameNumFromBufferLength(bufferLength, defaultVCType, defaultSplitedCols);

    vcTypeHeader_t defaultHeader = generateHeaderWithSpecificValue(defaultVCType, defaultLogicalID, defaultPhysicalID,
                                                                   defaultSQ, totalFrameSize,
                                                                   totalFrameNum);

    printf("fillHeaders start:\n");
    fillHeadersToSplitBuffer(defaultHeader, defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    printHeapOutterBufferContent(defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("fillMFI Value start:\n");
    printf("Initial MFI Value: %u\n", defaultStartMFI);

    fillMFIToSplitBuffer(defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer, defaultStartMFI);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    printHeapOutterBufferContent(defaultVCType, defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("\n");
    //////////////////////////////////////////////////////////////  outputToFiles unit test
    printf("outputToFiles test start!\n\n");

#ifdef OUTPUT_GENERATE_BLOCK_DATA
    printf("generateBufferToFile: \n");
    outputOriginBufferToFile("GenerateData.dat", mallocBuffer, bufferLength);
#endif

    printf("generateSplitedBufferToFile: \n");
    outputToFiles(defaultSplitedCols, oneLineLength, outMallocBuffer, defaultPhysicalID);

    free(mallocBuffer);
    free(outMallocBuffer);
}

struct numTypeParameter {
    uint16_t defaultStructureMode;
    enum VC_TYPE defaultVCType;
    uint16_t defaultSplitedCols;

    uint16_t defaultPhysicalID;
    uint16_t defaultLogicalID;
    uint16_t defaultStartMFI;
    enum GENERATE_DATA_TYPE defaultGenDataType;

    size_t defaultGenFrameNum;
    size_t defaultBufferLength; // 总 buffer 长度

    char inputfilename[256];
};

struct strTypeParameter {
    char structuremode[10];
    char vctype[10];
    char gentype[10];
    char inputfile[256];
    char genlength[100];
    char genframenum[50];
    char physicalid[10];
    char logicalid[10];
    char startmfi[10];
};

void printNumTypeParameterContent(struct numTypeParameter numParameter) {
    printf("defaultVCType: %s \n",
           numParameter.defaultVCType == 4 ? "VC_4" : numParameter.defaultVCType == 12 ? "VC_12"
                                                                                       : "Unknown vcType");

    printf("defaultSplitedCols: %d\n", numParameter.defaultSplitedCols);
    printf("defaultPhysicalID: %d\n", numParameter.defaultPhysicalID);
    printf("defaultLogicalID: %d\n", numParameter.defaultLogicalID);

    printf("defaultStartMFI: %d\n", numParameter.defaultStartMFI);

    switch (numParameter.defaultGenDataType) {
        case FIXED_60A1DA8E:
            printf("defaultGenDataType: %s", "FIXED_60A1DA8E\n");
            break;

        case FIXED_00TOFF:
            printf("defaultGenDataType: %s", "FIXED_00TOFF\n");
            break;

        case FIXED_LogicINC:
            printf("defaultGenDataType: %s", "FIXED_LogicINC\n");
            break;

        case FIXED_LowerINC_HigherLOID:
            printf("defaultGenDataType: %s", "FIXED_LowerINC_HigherLOID\n");
            break;

        default:
            printf("defaultGenDataType: %s", "Unknown GenDataType\n");
            break;
    }

    printf("defaultGenFrameNum: %zu\n", numParameter.defaultGenFrameNum);
    printf("defaultBufferLength: %zu\n", numParameter.defaultBufferLength);
    printf("inputfilename: %s\n", numParameter.inputfilename);
}

void printHelpMessage(char *argv[0]) {
    const char help_template[] = {
            "\nUsage: %s [OPTIONS]\n"
            "Example Param:  --vctype VC-12-3v --gentype 60A1DA8E --genframenum 30 --physicalid 32 --logicalid 30 --startmfi 10\n\n"
            "Options:\n"
            "  -S, --structuremode 0-512,9999  Structure mode                               \n"
            "  -v, --vctype=VC-'n1'-'n2'v        Set VC type.                               \n"
            "      example: 'VC-4-3v'  set VCtype to VC-4, set Split Channel to 3 channel.  \n"
            "  -g, --gentype=GEN_TYPE      Set generate Data type .                         \n"
            "      available GEN_TYPE:                                                      \n"
            "                 1. 60A1DA8E                                                   \n"
            "                 2. LOWERINC_HIGHERLOID                                        \n"
            "                 3. LOID_INC                                                   \n"
            "                 4. 00TOFF                                                     \n"
            "                 5. INPUTFILE                                                  \n"
            "      -i, --inputfile=FILEPATH   ONLY set -g,--gentype PATH works.             \n"
            "             generate Data will set stream to FILE stream.                     \n"
            "  -l, --genlength=LENGTH      Set generate Data length.                        \n"
            "  -n, --genframenum=FRAMENUM  Set generate Data Frame number.                  \n"
            "  -P, --physicalid=PHYSICALID Set physical ID value.                           \n"
            "  -L, --logicalid=LOGICALID   Set logical ID value.                            \n"
            "  -m, --startmfi=START_MFI    Set starting point MFI value.                    \n"
            "  -v, --verbose               Verbose mode.  (May not work (QwQ) )             \n"
            "  -h, --help                  Show this help message and exit.                 \n\n"
            "Some Parameters sample like this:\n"
            " --structuremode 0 --gentype 00TOFF --genframenum 30 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"
            " --structuremode 1 --gentype 0 --genframenum 640 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"
            " --structuremode 2 --gentype 1 --genframenum 320 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"
            " --structuremode 256 --gentype 2 --genframenum 30 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"
            " --structuremode 257 --gentype LOWERINC_HIGHERLOID --genframenum 640 --startphysicalid 0 --logicalid 0 --startmfi 100\n"
            " --structuremode 512 --gentype 00TOFF --genframenum 126 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"
            " --structuremode 9999 --vctype VC-4-12v --gentype 00toff --genframenum 120 --startphysicalid 0 --startlogicalid 0 --startmfi 100\n"


    };
    printf(help_template, argv[0]);
}

struct strTypeParameter parameterPasserToStrsType(int argc, char *argv[]) {
    struct strTypeParameter strParameterVal = {0};

    int option;
    int flagVerbose = 0;
    bool structuremode_flag = false;
    bool genframenum_flag = false;
    bool genlength_flag = false;

    static struct option long_options[] = {
            {"structuremode",   required_argument, 0, 'S'},
            {"vctype",          required_argument, 0, 'v'},
            {"gentype",         required_argument, 0, 'g'},
            {"inputfile",       required_argument, 0, 'i'},

            {"genlength",       required_argument, 0, 'l'},
            {"genframenum",     required_argument, 0, 'n'},

            {"startphysicalid", required_argument, 0, 'P'},
            {"startlogicalid",  required_argument, 0, 'L'},

            {"startmfi",        required_argument, 0, 'm'},

            {"help",            no_argument,       0, 'h'},
            {0,                 0,                 0, 0} // 用于指示长选项数组结束
    };

    int option_index = 0;
    // 使用getopt_long解析命令行参数
    while ((option = getopt_long(argc, argv, "S:v:g:i:l:n:P:L:m:h", long_options, &option_index)) != -1) {
        switch (option) {
            case 'S':
                if (optarg) {
                    structuremode_flag = true;
                    strcpy_s(strParameterVal.structuremode, sizeof(strParameterVal.structuremode), optarg);
                }
                break;

            case 'v':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.vctype, sizeof(strParameterVal.vctype), optarg);
                }
                //                printf("\n");
                break;
            case 'g':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);

                    strcpy_s(strParameterVal.gentype, sizeof(strParameterVal.gentype), optarg);
                }
                //                printf("\n");
                break;
            case 'i':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.inputfile, sizeof(strParameterVal.inputfile), optarg);
                }
                //                printf("\n");
                break;

            case 'l':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    genlength_flag = true;
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.genlength, sizeof(strParameterVal.genlength), optarg);
                }
                //                printf("\n");
                break;
            case 'n':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    genframenum_flag = true;
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.genframenum, sizeof(strParameterVal.genframenum), optarg);
                }
                //                printf("\n");
                break;
            case 'P':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.physicalid, sizeof(strParameterVal.physicalid), optarg);
                }
                //                printf("\n");
                break;
            case 'L':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.logicalid, sizeof(strParameterVal.logicalid), optarg);
                }
                //                printf("\n");
                break;
            case 'm':
                //                printf("option %s", long_options[option_index].name);
                if (optarg) {
                    //                    printf(" with arg %s", optarg);
                    strcpy_s(strParameterVal.startmfi, sizeof(strParameterVal.startmfi), optarg);
                    //                    outputFileName = optarg;
                }
                //                printf("\n");
                break;
            case 'h':
                printHelpMessage(argv);
                exit(EXIT_SUCCESS);
                break;
            case '?':
                // 未知选项或缺少参数
                exit(EXIT_FAILURE);
            default:
                printf("Unknown option\n");
                //
                exit(0);
        }
    }
    printf("\n");

    // 这东西说不好就有人想生成一个0bufferLength的需求呢?   233333
    //    if (!(structuremode_flag && (genframenum_flag || genlength_flag))){
    //        printf("Please set genframenum or genlength!\n");
    //        exit(EXIT_FAILURE);
    //    }


    return strParameterVal;
}

bool extractVCTypeValues(const char *inputString, int *n1, int *n2) {
    // 假设输入字符串的形式为 "VC-n1-n2v"
    const char *prefix = "VC-";

    if (strncmp(inputString, prefix, strlen(prefix)) != 0) {
        return false;
    }

    // 解析n1和n2
    const char *n1Start = inputString + strlen(prefix);
    char *n2Start;
    *n1 = strtol(n1Start, &n2Start, 10);
    if (n1Start == n2Start) {
        return false; // 无法解析n1
    }

    // 检查n2后面的字符是否合法
    if (*n2Start != '-' || *(n2Start + 1) == '\0') {
        return false;
    }

    *n2 = strtol(n2Start + 1, NULL, 10);
    return true;
}

struct numTypeParameter parseStrParameterToNumParameter(struct strTypeParameter strParameter) {
    uint16_t defaultStructureMode = 9999;

    enum VC_TYPE defaultVCType = 0;
    uint16_t defaultSplitedCols = 0;

    uint16_t defaultPhysicalID = 0;
    uint16_t defaultLogicalID = 0;
    uint16_t defaultStartMFI = 0;
    enum GENERATE_DATA_TYPE defaultGenDataType = FIXED_60A1DA8E;

    size_t defaultGenFrameNum = 0;
    size_t defaultBufferLength = 0; // 总 buffer 长度

    char defaultInputFilePath[256] = {0};

    if (strtol(strParameter.structuremode, NULL, 10) == 9999) {
        // 如果模式 不是9999, 为单通道产生模式
        // parse VCType SplitChannel
        int vc_n_type = VC_4, split_channel = 1;
        if (extractVCTypeValues(strParameter.vctype, &vc_n_type, &split_channel)) {
            printf("VCType = %d, Split channel = %d\n", vc_n_type, split_channel);
            switch (vc_n_type) {
                case 4:
                    defaultVCType = VC_4;
                    break;
                case 12:
                    defaultVCType = VC_12;
                    break;
                default:
                    printf("\033[31mERROR: \033[0m VCType %d NOT Support!\n", vc_n_type);
                    exit(EXIT_FAILURE);
            }

            if (split_channel <= 0 || split_channel >= 64) {
                printf("\033[31mERROR: \033[0m Split Channel Number %d Illegal!\n", vc_n_type);
                exit(EXIT_FAILURE);
            } else {
                defaultSplitedCols = split_channel;
            }
        } else {
            printf("\033[31mERROR: \033[0m VCType strParameter analyzing ERROR!\n");
            exit(EXIT_FAILURE);
        }

    } else {
        // 多通道模式, 这里可以添加校验.
        defaultVCType = VC_4;
        defaultSplitedCols = 1;
    }


    // physicalID, logicalID
    defaultPhysicalID = strtol(strParameter.physicalid, NULL, 10);
    defaultLogicalID = strtol(strParameter.logicalid, NULL, 10);

    // genFrameNum, genBufferLength
    defaultGenFrameNum = strtol(strParameter.genframenum, NULL, 10);
    defaultBufferLength = strtol(strParameter.genlength, NULL, 10);
    // startMFI
    defaultStartMFI = strtol(strParameter.startmfi, NULL, 10);

    // genDataType
    if (strcmp(strParameter.gentype, "0") == 0 || strcmp(strParameter.gentype, "60A1DA8E") == 0) {
        defaultGenDataType = FIXED_60A1DA8E;
    } else if (strcmp(strParameter.gentype, "1") == 0 || strcmp(strParameter.gentype, "LOWERINC_HIGHERLOID") == 0) {
        defaultGenDataType = FIXED_LowerINC_HigherLOID;
    } else if (strcmp(strParameter.gentype, "2") == 0 || strcmp(strParameter.gentype, "LOID_INC") == 0) {
        defaultGenDataType = FIXED_LogicINC;
    } else if (strcmp(strParameter.gentype, "3") == 0 || strcmp(strParameter.gentype, "00TOFF") == 0) {
        defaultGenDataType = FIXED_00TOFF;
    } else if (strcmp(strParameter.gentype, "INPUTFILE") == 0) {
        defaultGenDataType = INPUTFILE;
        if (isblank(defaultInputFilePath[0]) || defaultInputFilePath[0] == '\0') {
            printf("\033[31mERROR: \033[0m Inputfile Path need or valid! Please check inputfile path!\n");
            exit(EXIT_FAILURE);
        }
    } else {
        printf("\033[33mWARN: \033[0m Invalid GenDataType: '%s' ,Will set to '60A1DA8E'!\n", strParameter.gentype);
        defaultGenDataType = FIXED_60A1DA8E;
    }

    defaultStructureMode = strtol(strParameter.structuremode, NULL, 10);


    struct numTypeParameter retVal = {0};
    retVal.defaultStructureMode = defaultStructureMode;
    retVal.defaultVCType = defaultVCType;
    retVal.defaultSplitedCols = defaultSplitedCols;
    retVal.defaultPhysicalID = defaultPhysicalID;
    retVal.defaultLogicalID = defaultLogicalID;

    retVal.defaultStartMFI = defaultStartMFI;
    retVal.defaultGenDataType = defaultGenDataType;
    retVal.defaultGenFrameNum = defaultGenFrameNum;
    retVal.defaultBufferLength = defaultBufferLength;
    strcpy_s(retVal.inputfilename, sizeof(retVal.inputfilename), defaultInputFilePath);

//    printNumTypeParameterContent(retVal);

    return retVal;
}


void valdatingNumParameters(struct numTypeParameter *numParameter) {

    if (numParameter->defaultLogicalID < 0 || numParameter->defaultLogicalID >= 4095) {
        printf("\033[31mERROR: \033[0m LogicalID Value Invalid!\n");
        exit(EXIT_FAILURE);
    }

    if (numParameter->defaultPhysicalID < 0 || numParameter->defaultPhysicalID >= 4095) {
        printf("\033[31mERROR: \033[0m PhysicalID Value Invalid!\n");
        exit(EXIT_FAILURE);
    }

    if (numParameter->defaultGenFrameNum <= 0 && numParameter->defaultBufferLength <= 0) {
        printf("\033[31mERROR: \033[0m GenFrameNum or BufferLength Value Invalid!\n");
        exit(EXIT_FAILURE);
    } else if (numParameter->defaultGenFrameNum > 0 && numParameter->defaultBufferLength > 0) {
        printf("\033[33mWARN: \033[0m GenFrameNum and BufferLength both Setted! Will get 'BIGGER Buffer Byte' ones!\n");
        if (getBufferLengthFromGenFrameNum(numParameter->defaultGenFrameNum, numParameter->defaultVCType) >=
            numParameter->defaultBufferLength) {
            numParameter->defaultBufferLength = 0;
        } else {
            numParameter->defaultGenFrameNum = 0;
        }
    }

    if (numParameter->defaultStartMFI < 0 || numParameter->defaultStartMFI > 4095) {
        printf("\033[31mERROR: \033[0m defaultStartMFI Value Invalid!\n");
        exit(EXIT_FAILURE);
    }

    ///////////////////////////////////////  InputFile->
    // --inputfile setted, BUT --gentype not INPUTFILE
    if (!(isblank(numParameter->inputfilename[0]) || numParameter->inputfilename[0] == '\0') &&
        numParameter->defaultGenDataType != INPUTFILE) {
        printf("\033[33mWARN: \033[0m Filepath set, BUT '--gentype NOT INPUTFILE', skipping!\n");
    }

    if (numParameter->defaultGenDataType == INPUTFILE) {
        FILE *file = fopen(numParameter->inputfilename, "r");
        if (file == NULL) {
            printf("File '%s' does not exist or cannot be opened->\n", numParameter->inputfilename);
            printf("Aborting->->.\n");
            exit(EXIT_FAILURE);
        }
    }

    // 起始physicalID + 要分成多少行 应当小于 最大物理通道数
    if (numParameter->defaultSplitedCols + numParameter->defaultPhysicalID > 4032) {
        printf("\033[31mERROR: \033[0m Channel Not Enough! Please ensure 'Channel'+'physicalID' <= 4032 \n");
        exit(EXIT_FAILURE);
    }

    if (numParameter->defaultSplitedCols == 0) {
        printf("\033[31mERROR: \033[0m Split Channel cannot be 0!\n");
        exit(EXIT_FAILURE);
    }

    if (numParameter->defaultGenFrameNum % numParameter->defaultSplitedCols != 0) {
        printf("\033[33mWARN: \033[0m GenFrameNum should be TIMES of Channel Number. \n"
               "May cause last few bytes Incomplete filling like 'BB' \n\n");
    }


}

void singleChannelGenerator(struct numTypeParameter numParam) {
    // -S 9999 --vctype VC-12-60v --gentype 00toff --genframenum 360 --startphysicalid 10 --logicalid 30 --startmfi 100

    printNumTypeParameterContent(numParam);

    // 开辟对应的空间     - 生成数据的空间
    // 默认使用的是 genFrameNum.
    size_t bufferLength = getBufferLengthFromGenFrameNum(numParam.defaultGenFrameNum, numParam.defaultVCType);
    // 如果输入了 genlength. 上面的返回结果是0.
    if (bufferLength == 0) {
        bufferLength = numParam.defaultBufferLength;
    }


    size_t filledBufferLength = bufferLength;   // 默认情况下, 生成的数据量和开辟空间大小一致.

    void *mallocBuffer = malloc(bufferLength); // 分配空间
    if (mallocBuffer == NULL) {
        printf("mallocBuffer -> NULL, malloc FAILED! Aborting...\n");
        exit(EXIT_FAILURE);
    } else {
        printf("mallocBuffer origin data length: %zu \n", bufferLength);
    }

    ///////////////////////////////////////////////////////////////  malloc heap memory unit test
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    ///////////////////////////////////////////////////////////////  fillBlockWithSpecificValue unit test

    fillBlockWithSpecificValue(mallocBuffer, bufferLength, 0xBB);
    printf("fillBuffer with BB: \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif
    printf("\n");

    ///////////////////////////////////////////////////////////////  generatePersistData unit test
    switch (numParam.defaultGenDataType) {
        case FIXED_00TOFF:
            generatePersistData_00toFF(mallocBuffer, bufferLength, filledBufferLength);
            break;

        case FIXED_60A1DA8E:
            generatePersistData_60A1DA8E(mallocBuffer, bufferLength, filledBufferLength);
            break;

        case FIXED_LowerINC_HigherLOID:
            generatePersistData_LowerIncrementHigherLogicalID(mallocBuffer, bufferLength, filledBufferLength,
                                                              numParam.defaultLogicalID);
            break;

        case FIXED_LogicINC:
            generatePersistData_ChannelIncrement(mallocBuffer, bufferLength, filledBufferLength,
                                                 numParam.defaultLogicalID);
            break;

        case INPUTFILE:
            printf("INPUTFILE not supported yet...\n");
            exit(EXIT_FAILURE);
    }

    printf("generatePersistData: \n");
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapBufferMemory(mallocBuffer, bufferLength);
#endif

    printf("Only print LAST 20 Bytes:\n");
    printHeapBufferMemoryLast20Bytes(mallocBuffer, bufferLength);

    printf("\n");
    ///////////////////////////////////////////////////////////////  reversePersistData unit test
//    printf("reverseBufferInPlace: \n");
//    printf("reversed      test: \n");
//    reverseBufferInPlace(mallocBuffer, bufferLength);
//#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
//        printHeapBufferMemory(mallocBuffer, bufferLength);
//#endif

//    printf("reversed to origin: \n");
//    reverseBufferInPlace(mallocBuffer, bufferLength);
//#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
//        printHeapBufferMemory(mallocBuffer, bufferLength);
//#endif

//    void *mallocBuffer2 = malloc(bufferLength);
//    reverseBufferWithExtraBuffer(mallocBuffer, bufferLength, mallocBuffer2);
//    printf("reversed to extra : \n");
//#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
//        printHeapBufferMemory(mallocBuffer2, bufferLength);
//#endif
//    free(mallocBuffer2);
//    printf("ExtraBuffer data freed! \n");

    printf("\n");
    ///////////////////////////////////////////////////////////////  getters unit test

    size_t testGettersNum1 = getFrameNumOneLineFromBufferLength(bufferLength, numParam.defaultVCType,
                                                                numParam.defaultSplitedCols);
    printf("getFrameNumOneLineFromBufferLength() returns: %zu\n", testGettersNum1);
    size_t testGettersNum2 = getFrameNumFromBufferLength(bufferLength, numParam.defaultVCType,
                                                         numParam.defaultSplitedCols);
    printf("getFrameNumFromBufferLength() returns: %zu\n", testGettersNum2);
    size_t testGettersNum3 = getTotalFullLengthOneLineFromBufferLength(bufferLength, numParam.defaultVCType,
                                                                       numParam.defaultSplitedCols);
    printf("getTotalFullLengthOneLineFromBufferLength: %zu\n", testGettersNum3);
    size_t testGettersNum4 = getTotalFullLengthFormBufferLength(bufferLength, numParam.defaultVCType,
                                                                numParam.defaultSplitedCols);
    printf("getTotalFullLengthFormBufferLength: %zu\n", testGettersNum4);
    size_t testGettersNum5 = getFrameNumOneLineFromOneLineLength(numParam.defaultVCType, testGettersNum3);
    printf("getFrameNumOneLineFromOneLineLength: %zu\n", testGettersNum5);

    printf("\n");
    ///////////////////////////////////////////////////////////////  fillDataToSplitBuffer unit test

    printf("/////////////////////////////////////////////////////////////////////////////////////////////////////////////\n");
    printf("fillDataToSplitBuffer test start!\n\n");

    size_t oneLineLength = getTotalFullLengthOneLineFromBufferLength(bufferLength, numParam.defaultVCType,
                                                                     numParam.defaultSplitedCols);
    // 开辟对应的空间     - 产出数据的空间
    size_t outBufferLength = getTotalFullLengthFormBufferLength(bufferLength, numParam.defaultVCType,
                                                                numParam.defaultSplitedCols);
    void *outMallocBuffer = malloc(
            getTotalFullLengthFormBufferLength(bufferLength, numParam.defaultVCType, numParam.defaultSplitedCols));
    if (outMallocBuffer) {
        printf("outBufferMalloced!\n");
    } else {
        printf("outBufferMalloc ERROR!\n");
        exit(EXIT_FAILURE);
    }

    printf("fillBlockWithSpecificValue: 0xBB\n");
    fillBlockWithSpecificValue(outMallocBuffer,
                               getTotalFullLengthFormBufferLength(bufferLength, numParam.defaultVCType,
                                                                  numParam.defaultSplitedCols),
                               0xBB);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapOutterBufferContent(numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("\n");
    ///////////////////////////////////////////////////////////////  fillSplitDataToSplitBuffer unit test

    printf("splitIntoMutipleBuffer: \n");
    splitIntoMutipleBuffer(mallocBuffer, bufferLength, numParam.defaultVCType, numParam.defaultSplitedCols,
                           oneLineLength,
                           outMallocBuffer);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapOutterBufferContent(numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("\n");
    //////////////////////////////////////////////////////////////  fillHeaders unit test

    size_t totalFrameSize = getTotalFullLengthFormBufferLength(bufferLength, numParam.defaultVCType,
                                                               numParam.defaultSplitedCols);
    size_t totalFrameNum = getFrameNumFromBufferLength(bufferLength, numParam.defaultVCType,
                                                       numParam.defaultSplitedCols);


    vcTypeHeader_t defaultHeader = generateHeaderWithSpecificValue(numParam.defaultVCType, numParam.defaultLogicalID,
                                                                   numParam.defaultPhysicalID,
                                                                   0, totalFrameSize,
                                                                   totalFrameNum);

    printf("fillHeaders start:\n");
    fillHeadersToSplitBuffer(defaultHeader, numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength,
                             outMallocBuffer);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    //    printHeapOutterBufferContent(numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    printf("fillMFI Value start:\n");
    printf("Initial MFI Value: %u\n", numParam.defaultStartMFI);

    fillMFIToSplitBuffer(numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength, outMallocBuffer,
                         numParam.defaultStartMFI);
#ifdef DEBUG_PRINT_ALL_BUFFER_CONTENT
    printHeapOutterBufferContent(numParam.defaultVCType, numParam.defaultSplitedCols, oneLineLength, outMallocBuffer);
#endif

    // 最终打印Header中的内容
    headerReaderFromSplitBuffer(numParam.defaultSplitedCols, oneLineLength, outMallocBuffer);

    printf("\n");
    //////////////////////////////////////////////////////////////  outputToFiles unit test
//    printf("outputToFiles test start!\n\n");

#ifdef OUTPUT_GENERATE_BLOCK_DATA
    if (numParam.defaultStructureMode == 9999) {
        printf("generateBufferToFile: \n");
        outputOriginBufferToFile("GenerateData.dat", mallocBuffer, bufferLength);
    }
#endif

    printf("generateSplitedBufferToFile: \n");
    outputToFiles(numParam.defaultSplitedCols, oneLineLength, outMallocBuffer, numParam.defaultPhysicalID);

    free(mallocBuffer);
    free(outMallocBuffer);


}

void multipleChannelGenerator(struct numTypeParameter numParam) {
    struct numTypeParameter tempParam = {0};

    switch (numParam.defaultStructureMode) {
// 0~255：全 VC-4 模式（10G SDH 中包含 64 个 VC-4）
//0:  全 VC-4 模式，每个 VC-4 为一个单独的逻辑通道
        case 0:
            // -S 0 --gentype 00toff --genframenum 30 --startphysicalid 0 --startlogicalid 0 --startmfi 100
            tempParam.defaultStructureMode = 0;
            tempParam.defaultSplitedCols = 1;
            tempParam.defaultVCType = VC_4;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;

            valdatingNumParameters(&tempParam);

            for (int i = 0; i < 64; ++i) {
                singleChannelGenerator(tempParam);
                tempParam.defaultLogicalID++;
                tempParam.defaultPhysicalID++;
            }

            break;

//1：全 VC-4 模式，64 个 VC-4 组合成 1 个逻辑通道
        case 1:
            // -S 1 --gentype 00toff --genframenum 640 --startphysicalid 0 --startlogicalid 0 --startmfi 100
            tempParam.defaultStructureMode = 1;
            tempParam.defaultSplitedCols = 64;
            tempParam.defaultVCType = VC_4;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;


            valdatingNumParameters(&tempParam);
            singleChannelGenerator(tempParam);

            break;
//2：全 VC-4 模式，32 个 VC-4 组合成 1 个逻辑通道，其它每个 VC-4 为独立的逻辑通道
        case 2:
            //  -S 2 --gentype 00toff --genframenum 320 --startphysicalid 0 --startlogicalid 0 --startmfi 100
            // 32个逻辑1
            tempParam.defaultStructureMode = 2;
            tempParam.defaultSplitedCols = 32;
            tempParam.defaultVCType = VC_4;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;

            valdatingNumParameters(&tempParam);
            singleChannelGenerator(tempParam);


            tempParam.defaultPhysicalID += 32;
            tempParam.defaultLogicalID++;

            tempParam.defaultStructureMode = 2;
            tempParam.defaultSplitedCols = 1;
            tempParam.defaultVCType = VC_4;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;

            valdatingNumParameters(&tempParam);
            for (int i = 0; i < 32; ++i) {
                singleChannelGenerator(tempParam);
                tempParam.defaultLogicalID++;
                tempParam.defaultPhysicalID++;
            }

            break;



//256~511：全 VC-12 模式（10G SDH 中包含 4032 个 VC-4）
//256:  全 VC-12 模式，每个 VC-12 为一个单独的逻辑通道
        case 256:
            //  -S 256 --gentype 00toff --genframenum 30 --startphysicalid 0 --startlogicalid 0 --startmfi 100  > mode256_output.txt
            tempParam.defaultStructureMode = 256;
            tempParam.defaultSplitedCols = 1;
            tempParam.defaultVCType = VC_12;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;
            valdatingNumParameters(&tempParam);

            for (int i = 0; i < 4032; ++i) {
                singleChannelGenerator(tempParam);
                tempParam.defaultLogicalID++;
                tempParam.defaultPhysicalID++;
            }


            break;
//257：全 VC-12 模式，每 64 个 VC-12 组合成 1 个逻辑通道（需注意 VC-12-Xv， X 的值最大为 64），共 63 个逻辑通道。
        case 257:
            //  -S 257 --gentype 00toff --genframenum 640 --startphysicalid 0 --startlogicalid 0 --startmfi 100  > mode257_output.txt
            tempParam.defaultStructureMode = 256;
            tempParam.defaultSplitedCols = 64;
            tempParam.defaultVCType = VC_12;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;
            valdatingNumParameters(&tempParam);

            for (int i = 0; i < 63; ++i) {
                singleChannelGenerator(tempParam);
                tempParam.defaultPhysicalID += 64;
                tempParam.defaultLogicalID++;
            }


            break;
//512~767：VC-4/VC-12 混合模式
//512：63 个 VC-4，63 个 VC-12；63 个 VC-4 组成 1 个逻辑通道，63 个 VC-12 组成 1 个逻辑通道。
        case 512:
            // --structuremode 512 --gentype 00toff --genframenum 126 --startphysicalid 0 --startlogicalid 0 --startmfi 100

            tempParam.defaultStructureMode = 512;
            tempParam.defaultSplitedCols = 63;
            tempParam.defaultVCType = VC_4;
            tempParam.defaultGenFrameNum = numParam.defaultGenFrameNum;
            tempParam.defaultPhysicalID = numParam.defaultPhysicalID;
            tempParam.defaultLogicalID = numParam.defaultLogicalID;
            tempParam.defaultBufferLength = numParam.defaultBufferLength;
            tempParam.defaultStartMFI = numParam.defaultStartMFI;
            tempParam.defaultGenDataType = numParam.defaultGenDataType;
            valdatingNumParameters(&tempParam);

            singleChannelGenerator(tempParam);

            tempParam.defaultPhysicalID += 63;
            tempParam.defaultLogicalID++;

            ////////
            tempParam.defaultSplitedCols = 63;
            tempParam.defaultVCType = VC_12;
            valdatingNumParameters(&tempParam);
            singleChannelGenerator(tempParam);


            break;

//我们暂时只以上产生 6 种通道结构，并用 STRUCTURE_MODE 参数为 0、1、2、 256、257、512 分别表示这 6 种结构。

        default:
            printf("Unknown STRUCTURE_MODE value...\n");
            exit(EXIT_FAILURE);
    }

}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void testAllFuncitonWithParameterPasser(int argc, char *argv[]) {
//    printf("Param -> strParam start:\n");
    struct strTypeParameter strParam = parameterPasserToStrsType(argc, argv);
//    printf("strParam -> numParam start:\n");

    struct numTypeParameter numParam = parseStrParameterToNumParameter(strParam);

    if (numParam.defaultStructureMode == 9999) {
        valdatingNumParameters(&numParam);
        singleChannelGenerator(numParam);
    } else {
        multipleChannelGenerator(numParam);
    }

}


void testGenerateData() {
    size_t bufferLength = 39;
    size_t filledBufferLength = 39;
    uint8_t *buffer = malloc(bufferLength);
    fillBlockWithSpecificValue(buffer, bufferLength, 0xBB);

    if (buffer) {

        // 仅测试后面两种新增加的填充方法
        printf("Generating LowerLoopIncrementData\n");
        size_t filledLength = generatePersistData_LowerIncrementHigherLogicalID(buffer, bufferLength,
                                                                                filledBufferLength, 10);
        for (size_t i = 0; i < bufferLength; i++) {
            printf("%02X ", buffer[i]);

        }
        printf("\n");

        printf("Generating ChannelIncrement\n");
        filledLength = fillBlockWithSpecificValue(buffer, bufferLength, 0xBB);
        generatePersistData_ChannelIncrement(buffer, bufferLength, filledBufferLength, 10);

        for (size_t i = 0; i < bufferLength; i++) {
            printf("%02X ", buffer[i]);

        }
        printf("\n");


        free(buffer);
    } else {
        printf("内存分配失败\n");
    }
}

int main(int argc, char *argv[]) {

    //    testAllFunctionsWithNoMalloc();       // version 1.0

    //    testAllFunctionsWithMalloc();       // version 1.2

    testAllFuncitonWithParameterPasser(argc, argv);

    // 测试的时候可以使用  --vctype VC-12-3v --gentype 60a1da8e --genlength 99999 --genframenum 30 --startphysicalid 32 --logicalid 30 --startmfi 10
    // --vctype VC-12-60v --gentype 00toff --genframenum 360000 --startphysicalid 10 --logicalid 30 --startmfi 100

    return 0;
}
